﻿using Google.Protobuf.WellKnownTypes;
using IdentityModel.Client;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Http.Features;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Identity.Client;
using MyWeb.ServiceBus.Services.Db;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace MyWeb.ServiceBus.Extensions.Middleware
{
    public class HttpContextMiddleware
    {
        private readonly RequestDelegate _next;
        /// <summary>
        /// 计时器
        /// </summary>
        private Stopwatch? _stopwatch;
        /// <summary>
        /// 构造 Http 请求中间件
        /// </summary>
        /// <param name="next"></param>
        /// <param name="loggerFactory"></param>
        /// <param name="cacheService"></param>
        public HttpContextMiddleware(RequestDelegate next) => _next = next;

        public async Task InvokeAsync(HttpContext context)
        {

            var path = context.Request.Path.ToUriComponent();
            // 获取原始请求的查询参数
            var queryString = context.Request.QueryString.ToUriComponent();
            if (path.IndexOf("/system/") == 0)
            {
                // 构建目标地址
                var requestUrl = $"https://localhost:7234/api/{path["/system/".Length..]}{queryString}";
                //this.SetRedirect(context, new Uri(requestUrl));
                this.SetLocationAsync(context, new Uri(requestUrl));
                //await SendHttpClientAsync(context, new Uri(requestUrl));
                return;
            }
            if (path.IndexOf("/quartz/") == 0)
            {
                var requestUrl = $"https://localhost:9235{path.Replace("/quartz/", "/api/")}{queryString}";
                this.SetRedirect(context, new Uri(requestUrl));
                return;
            }
            if (path.IndexOf("/ecsb/") == 0)
            {
                var requestUrl = $"http://localhost:8235/api/{path["/ecsb/".Length..]}{queryString}";
                this.SetLocationAsync(context, new Uri(requestUrl));
                return;
            }

            // 继续传递请求给下一个中间件
            await _next(context);
        }

        /// <summary>
        /// 发送307临时重定向
        /// </summary>
        /// <param name="context"></param>
        /// <param name="uri"></param>
        private async Task SetLocationAsync(HttpContext context, Uri uri)
        {
            // 设置允许跨域请求
            context.Response.Headers.Add("Access-Control-Allow-Origin", "*");
            // 设置允许使用凭证（credentials）的选项
            context.Response.Headers.Add("Access-Control-Allow-Credentials", "true");
            context.Response.Headers.Add("Access-Control-Allow-Headers", "Authorization");
            

            if (context.Request.Method.Equals("POST", StringComparison.OrdinalIgnoreCase))
            {
                context.Request.EnableBuffering();
                var requestBody = await new StreamReader(context.Request.Body).ReadToEndAsync();
                context.Request.Body.Seek(0, SeekOrigin.Begin);

                var requestHeaders = context.Request.Headers.ToDictionary(h => h.Key, h => h.Value.ToString());
                // Set request headers to be accessed in the redirected middleware
                context.Items["RequestHeaders"] = requestHeaders;
                // Pass the request body to the new request
                context.Items["RequestBody"] = requestBody;
            }
            else
            {
                // Pass the request headers directly to the Response
                foreach (var header in context.Request.Headers)
                {
                    context.Response.Headers[header.Key] = header.Value;
                }
            }
            // 发送 HTTP 307 临时重定向响应，并保留原始请求的方法、路径和请求体参数
            context.Response.StatusCode = StatusCodes.Status307TemporaryRedirect;
            context.Response.Headers.Location = new Microsoft.Extensions.Primitives.StringValues(uri.ToString());

        }
        /// <summary>
        /// 设置跨域重定向请求
        /// </summary>
        /// <param name="context"></param>
        /// <param name="uri"></param>
        private void SetRedirect(HttpContext context, Uri uri)
        {

            // 保存原始请求的头部信息
            var originalHeaders = context.Request.Headers.ToDictionary(h => h.Key, h => h.Value.ToString());

            // 设置允许跨域
            context.Response.Headers.Add("Access-Control-Allow-Origin", "*");
            // 重定向到 WeatherForecast11
            context.Response.Redirect(uri.ToString());

            //获取重定向后的请求
            var redirectContext = context.Features.Get<IHttpResponseFeature>();
            if (redirectContext != null)
            {
                var redirectRequest = context.RequestServices.GetRequiredService<IHttpContextFactory>().Create((IFeatureCollection)redirectContext);

                // 将原始请求的头部信息复制到重定向后的请求中
                foreach (var header in originalHeaders)
                {
                    redirectRequest.Request.Headers[header.Key] = header.Value;
                }
            }
        }

        /// <summary>
        /// 发送Http请求
        /// </summary>
        /// <param name="context"></param>
        /// <param name="uri"></param>
        /// <returns></returns>
        private async Task SendHttpClientAsync(HttpContext context, Uri uri)
        {
            // 设置允许跨域
            //context.Response.Headers.Add("Access-Control-Allow-Origin", uri.Scheme + "://" + uri.Host + ":" + uri.Port);
            context.Response.Headers.Add("Access-Control-Allow-Origin", "http://localhost:8081");
            // 设置允许使用凭证（credentials）的选项
            context.Response.Headers.Add("Access-Control-Allow-Credentials", "true");
            context.Response.Headers.Add("Access-Control-Allow-Headers", "Authorization");
            var http = new HttpRequestMessage(new HttpMethod(context.Request.Method), uri);
            http.Headers.Clear();
            foreach (var header in context.Request.Headers.ToDictionary(h => h.Key, h => h.Value.ToString()))
            {
                http.Headers.Add(header.Key, header.Value);
            }

            // 读取 ASP.NET Core 的请求体参数
            using (var streamReader = new StreamReader(context.Request.Body))
            {
                var contentType = context.Request.ContentType ?? "application/json";
                var requestBody = await streamReader.ReadToEndAsync();
                // 添加请求体参数
                // 添加请求体参数到 HttpRequestMessage 的 Content 属性中
                http.Content = new StringContent(requestBody, Encoding.UTF8, new System.Net.Http.Headers.MediaTypeHeaderValue(contentType));
            }
            //if (context.Request.Form != null)
            //{
            //    //创建包含 form-data 参数的 MultipartFormDataContent 实例
            //    var formDataContent = new MultipartFormDataContent();
            //    foreach (var key in context.Request.Form.Keys)
            //    {
            //        formDataContent.Add(new StringContent(context.Request.Form[key].ToString() ?? ""), key);
            //    }
            //    http.Content = formDataContent;
            //}

            // 发送请求到目标地址
            var httpClient = new HttpClient();
            //httpClient.BaseAddress = new Uri(targetUrl);

            var Response = await httpClient.SendAsync(http);

            //context.Response.Clear();
            //// 将响应头部信息传递给 HttpContext
            //foreach (var (key, value) in Response.Headers)
            //{
            //    context.Response.Headers[key] = value.ToArray();
            //}
            context.Response.ContentType = "application/json";
            // 将目标地址的响应内容发送回客户端
            await Response.Content.CopyToAsync(context.Response.Body);

        }
    }
}
